bitkeeper revision 1.1185 (420cf3c8-bMMcsnH1kMVRwy5AQ-ecg)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 11 Feb 2005 18:04:56 +0000 (18:04 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 11 Feb 2005 18:04:56 +0000 (18:04 +0000)
Various mini-os and Xen fixes. The M2P table is now definitely
accessible (read-only) from guest context.
Signed-off-by: keir.fraser@cl.cam.ac.uk
16 files changed:
extras/mini-os/h/lib.h
extras/mini-os/h/mm.h
extras/mini-os/h/os.h
extras/mini-os/h/types.h
extras/mini-os/kernel.c
extras/mini-os/lib/printf.c
extras/mini-os/mm.c
extras/mini-os/traps.c
extras/mini-os/x86_64.S
xen/arch/x86/domain.c
xen/arch/x86/x86_32/domain_build.c
xen/arch/x86/x86_32/mm.c
xen/arch/x86/x86_64/domain_build.c
xen/arch/x86/x86_64/entry.S
xen/arch/x86/x86_64/mm.c
xen/include/asm-x86/x86_64/page.h

index d9996a2f857c74739384189b4210bc73fb8ab229..0b405ee0063f68c2b8a666014a61e5487e4b7c33 100644 (file)
 #ifndef _LIB_H_
 #define _LIB_H_
 
-
-/* variadic function support */
-typedef char *va_list;
-#define __va_size(type) \
-        (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
-#ifdef __GNUC__
-#define va_start(ap, last) \
-        ((ap) = (va_list)__builtin_next_arg(last))
-#else
-#define va_start(ap, last) \
-        ((ap) = (va_list)&(last) + __va_size(last))
-#endif
-#define va_arg(ap, type) \
-        (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
-#define va_end(ap)
-
+#include <stdarg.h>
 
 /* printing */
 #define printk  printf
index 5c6224db286032ae6d3ccf32946ba6860103ade2..c5f6ad47885c24fd8f7eaff4e73461ce4185a9fd 100644 (file)
@@ -1,20 +1,8 @@
 /* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
  *
- *        File: mm.h
- *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- *     Changes: 
- *              
- *        Date: Aug 2003
- * 
- * Environment: 
- * Description: 
+ * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
+ * Copyright (c) 2005, Keir A Fraser
  *
- ****************************************************************************
- * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $
- ****************************************************************************
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
  * deal in the Software without restriction, including without limitation the
 #ifndef _MM_H_
 #define _MM_H_
 
+#ifdef __x86_64__
+
+#define L1_PAGETABLE_SHIFT      12
+#define L2_PAGETABLE_SHIFT      21
+#define L3_PAGETABLE_SHIFT      30
+#define L4_PAGETABLE_SHIFT      39
+
+#define L1_PAGETABLE_ENTRIES    512
+#define L2_PAGETABLE_ENTRIES    512
+#define L3_PAGETABLE_ENTRIES    512
+#define L4_PAGETABLE_ENTRIES    512
+
+/* These are page-table limitations. Current CPUs support only 40-bit phys. */
+#define PADDR_BITS              52
+#define VADDR_BITS              48
+#define PADDR_MASK              ((1UL << PADDR_BITS)-1)
+#define VADDR_MASK              ((1UL << VADDR_BITS)-1)
+
+#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT)
+
+/* Given a virtual address, get an entry offset into a page table. */
+#define l1_table_offset(_a) \
+  (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
+#define l2_table_offset(_a) \
+  (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
+#define l3_table_offset(_a) \
+  (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
+#define l4_table_offset(_a) \
+  (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
+#endif
+
+#define _PAGE_PRESENT  0x001UL
+#define _PAGE_RW       0x002UL
+#define _PAGE_USER     0x004UL
+#define _PAGE_PWT      0x008UL
+#define _PAGE_PCD      0x010UL
+#define _PAGE_ACCESSED 0x020UL
+#define _PAGE_DIRTY    0x040UL
+#define _PAGE_PAT      0x080UL
+#define _PAGE_PSE      0x080UL
+#define _PAGE_GLOBAL   0x100UL
+
 #define PAGE_SHIFT      12
 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
 #define PAGE_MASK       (~(PAGE_SIZE-1))
@@ -72,6 +102,8 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine)
 
 #define to_phys(x)                 ((unsigned long)(x)-VIRT_START)
 #define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
+#define __va to_virt
+#define __pa to_phys
 
 void init_mm(void);
 unsigned long alloc_pages(int order);
index 6a0447ca39feac140a7af3126c0b4b1a6196b34f..434dd992f6a73ecabfa6d74bfd0609dbc815974b 100644 (file)
 #define __KERNEL_DS  FLAT_KERNEL_DS
 #define __KERNEL_SS  FLAT_KERNEL_SS
 
+#define TRAP_divide_error      0
+#define TRAP_debug             1
+#define TRAP_nmi               2
+#define TRAP_int3              3
+#define TRAP_overflow          4
+#define TRAP_bounds            5
+#define TRAP_invalid_op        6
+#define TRAP_no_device         7
+#define TRAP_double_fault      8
+#define TRAP_copro_seg         9
+#define TRAP_invalid_tss      10
+#define TRAP_no_segment       11
+#define TRAP_stack_error      12
+#define TRAP_gp_fault         13
+#define TRAP_page_fault       14
+#define TRAP_spurious_int     15
+#define TRAP_copro_error      16
+#define TRAP_alignment_check  17
+#define TRAP_machine_check    18
+#define TRAP_simd_error       19
+#define TRAP_deferred_nmi     31
+
 /* Everything below this point is not included by assembler (.S) files. */
 #ifndef __ASSEMBLY__
 
index 85ede91c138fd44393cf248dd80881c4bf6cc361..7bf103ab9c78756c162101a35b71386ff2fe2c55 100644 (file)
@@ -26,8 +26,13 @@ typedef signed short        s16;
 typedef unsigned short      u16;
 typedef signed int          s32;
 typedef unsigned int        u32;
+#ifdef __i386__
 typedef signed long long    s64;
 typedef unsigned long long  u64;
+#elif defined(__x86_64__)
+typedef signed long         s64;
+typedef unsigned long       u64;
+#endif
 
 typedef unsigned int        size_t;
 
@@ -35,7 +40,13 @@ typedef unsigned int        size_t;
 typedef unsigned char       u_char;
 typedef unsigned int        u_int;
 typedef unsigned long       u_long;
+#ifdef __i386__
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
 typedef unsigned int        uintptr_t;
+#elif defined(__x86_64__)
+typedef long                quad_t;
+typedef unsigned long       u_quad_t;
+typedef unsigned long       uintptr_t;
+#endif
 #endif /* _TYPES_H_ */
index a794145e68686e13075c1143e6760445010a5677..b6f89b8bbb1e58fcbfa1c38460361f342ef01779 100644 (file)
@@ -65,7 +65,7 @@ extern char shared_info[PAGE_SIZE];
 static shared_info_t *map_shared_info(unsigned long pa)
 {
     if ( HYPERVISOR_update_va_mapping(
-        (unsigned long)shared_info, pa | 3, UVMF_INVLPG) )
+        (unsigned long)shared_info, pa | 7, UVMF_INVLPG) )
     {
         printk("Failed to map shared_info!!\n");
         *(int*)0=0;
index f6232c40441860cd7f23e58bf04e6db924a524c5..a08bb20e6c8f199fabe18e9c553a89958066cb8a 100644 (file)
@@ -341,7 +341,9 @@ reswitch:   switch (ch = (u_char)*fmt++) {
                case 'p':
                        ul = (uintptr_t)va_arg(ap, void *);
                        base = 16;
-                       sharpflag = (width == 0);
+                       sharpflag = 0;
+            padc  = '0';
+            width = sizeof(uintptr_t)*2;
                        goto nosign;
                case 'q':
                        qflag = 1;
index 2bc87a5165008558796044d8cf436caf3185cdfa..40a80e2ccbbd614a60e0d12e89ced7292bf78e59 100644 (file)
@@ -84,6 +84,7 @@ void init_mm(void)
      */
 
     max_free_pfn = PFN_DOWN(to_phys(pgd));
+#ifdef __i386__
     {
         unsigned long *pgd = (unsigned long *)start_info.pt_base;
         unsigned long  pte;
@@ -110,6 +111,7 @@ void init_mm(void)
            (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
            (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn));
     init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn));   
+#endif
 
 
     /* Now initialise the physical->machine mapping table. */
index 858c54d3f23b75ae06300727895caf5b45fbed3a..70001282300da023bdefe096233456057734177a 100644 (file)
@@ -15,7 +15,6 @@ void overflow(void);
 void bounds(void);
 void invalid_op(void);
 void device_not_available(void);
-void double_fault(void);
 void coprocessor_segment_overrun(void);
 void invalid_TSS(void);
 void segment_not_present(void);
@@ -33,111 +32,134 @@ extern void do_exit(void);
 
 void dump_regs(struct pt_regs *regs)
 {
-    int in_kernel = 1;
     unsigned long esp;
     unsigned short ss;
 
+#ifdef __x86_64__
+    esp = regs->rsp;
+    ss  = regs->ss;
+#else
     esp = (unsigned long) (&regs->esp);
     ss = __KERNEL_DS;
     if (regs->cs & 2) {
-        in_kernel = 0;
         esp = regs->esp;
         ss = regs->ss & 0xffff;
     }
-    printf("EIP:    %04x:[<%p>]\n",
-           0xffff & regs->cs , regs->eip);
+#endif
+    printf("EIP:    %04x:[<%p>] %08x\n",
+           0xffff & regs->cs , regs->eip, regs->error_code);
     printf("EFLAGS: %p\n",regs->eflags);
     printf("eax: %p   ebx: %p   ecx: %p   edx: %p\n",
            regs->eax, regs->ebx, regs->ecx, regs->edx);
     printf("esi: %p   edi: %p   ebp: %p   esp: %p\n",
            regs->esi, regs->edi, regs->ebp, esp);
+#ifdef __x86_64__
+    printf("r8 : %p   r9 : %p   r10: %p   r11: %p\n",
+           regs->r8,  regs->r9,  regs->r10, regs->r11);
+    printf("r12: %p   r13: %p   r14: %p   r15: %p\n",
+           regs->r12, regs->r13, regs->r14, regs->r15);
+#endif
     printf("ds: %04x   es: %04x   ss: %04x\n",
            regs->ds & 0xffff, regs->es & 0xffff, ss);
-    printf("\n");
 }      
 
 
 static __inline__ void dump_code(unsigned long eip)
 {
-    unsigned *ptr = (unsigned *)eip;
+    unsigned char *ptr = (unsigned char *)eip;
     int x;
     
-    printk("Bytes at eip:\n");
-    for (x = -4; x < 5; x++)
-        printf("%p", ptr[x]);
+    printk("Bytes at eip: ");
+    for ( x = -4; x < 5; x++ )
+        printf("%02x ", ptr[x]);
+    printk("\n");
 }
 
-
-/*
- * C handlers here have their parameter-list constructed by the
- * assembler stubs above. Each one gets a pointer to a list
- * of register values (to be restored at end of exception).
- * Some will also receive an error code -- this is the code that
- * was generated by the processor for the underlying real exception. 
- * 
- * Note that the page-fault exception is special. It also receives
- * the faulting linear address. Normally this would be found in
- * register CR2, but that is not accessible in a virtualised OS.
- */
-
 static void __inline__ do_trap(int trapnr, char *str,
-                               struct pt_regs * regs, long error_code)
+                               struct pt_regs * regs)
 {
-    printk("FATAL:  Unhandled Trap (see mini-os:traps.c)");
-    printf("%d %s", trapnr, str);
+    printk("FATAL:  Unhandled Trap %d (%s)\n", trapnr, str);
     dump_regs(regs);
     dump_code(regs->eip);
-
     do_exit();
 }
 
 #define DO_ERROR(trapnr, str, name) \
-void do_##name(struct pt_regs * regs, long error_code) \
+void do_##name(struct pt_regs * regs) \
 { \
-       do_trap(trapnr, str, regs, error_code); \
+       do_trap(trapnr, str, regs); \
 }
 
 #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
-void do_##name(struct pt_regs * regs, long error_code) \
+void do_##name(struct pt_regs * regs) \
 { \
-       do_trap(trapnr, str, regs, error_code); \
+       do_trap(trapnr, str, regs); \
 }
 
 DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
-    DO_ERROR( 3, "int3", int3)
-    DO_ERROR( 4, "overflow", overflow)
-    DO_ERROR( 5, "bounds", bounds)
-    DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
-    DO_ERROR( 7, "device not available", device_not_available)
-    DO_ERROR( 8, "double fault", double_fault)
-    DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
-    DO_ERROR(10, "invalid TSS", invalid_TSS)
-    DO_ERROR(11, "segment not present", segment_not_present)
-    DO_ERROR(12, "stack segment", stack_segment)
-    DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
-    DO_ERROR(18, "machine check", machine_check)
-
-    void do_page_fault(struct pt_regs *regs, long error_code,
-                       unsigned long address)
+DO_ERROR( 3, "int3", int3)
+DO_ERROR( 4, "overflow", overflow)
+DO_ERROR( 5, "bounds", bounds)
+DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
+DO_ERROR( 7, "device not available", device_not_available)
+DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
+DO_ERROR(10, "invalid TSS", invalid_TSS)
+DO_ERROR(11, "segment not present", segment_not_present)
+DO_ERROR(12, "stack segment", stack_segment)
+DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
+DO_ERROR(18, "machine check", machine_check)
+
+extern unsigned long virt_cr2;
+void do_page_fault(struct pt_regs *regs)
 {
-    printk("Page fault\n");
-    printk("Address: 0x%p", address);
-    printk("Error Code: 0x%p", error_code);
-    printk("eip: \t 0x%p", regs->eip);
+    unsigned long addr = virt_cr2;
+    printk("Page fault at linear address %p\n", addr);
+    dump_regs(regs);
+    dump_code(regs->eip);
+#ifdef __x86_64__
+    {
+        unsigned long *tab = (unsigned long *)start_info.pt_base;
+        unsigned long page;
+    
+        printk("Pagetable walk from %p:\n", tab);
+        
+        page = tab[l4_table_offset(addr)];
+        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
+        printk(" L4 = %p (%p)\n", page, tab);
+        if ( !(page & _PAGE_PRESENT) )
+            goto out;
+
+        page = tab[l3_table_offset(addr)];
+        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
+        printk("  L3 = %p (%p)\n", page, tab);
+        if ( !(page & _PAGE_PRESENT) )
+            goto out;
+        
+        page = tab[l2_table_offset(addr)];
+        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
+        printk("   L2 = %p (%p) %s\n", page, tab,
+               (page & _PAGE_PSE) ? "(2MB)" : "");
+        if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
+            goto out;
+        
+        page = tab[l1_table_offset(addr)];
+        printk("    L1 = %p\n", page);
+    }
+#endif
+ out:
     do_exit();
 }
 
-void do_general_protection(struct pt_regs * regs, long error_code)
+void do_general_protection(struct pt_regs *regs)
 {
     printk("GPF\n");
-    printk("Error Code: 0x%p", error_code);
     dump_regs(regs);
     dump_code(regs->eip);
     do_exit();
 }
 
 
-void do_debug(struct pt_regs * regs, long error_code)
+void do_debug(struct pt_regs * regs)
 {
     printk("Debug exception\n");
 #define TF_MASK 0x100
@@ -146,9 +168,7 @@ void do_debug(struct pt_regs * regs, long error_code)
     do_exit();
 }
 
-
-
-void do_coprocessor_error(struct pt_regs * regs, long error_code)
+void do_coprocessor_error(struct pt_regs * regs)
 {
     printk("Copro error\n");
     dump_regs(regs);
@@ -161,14 +181,12 @@ void simd_math_error(void *eip)
     printk("SIMD error\n");
 }
 
-void do_simd_coprocessor_error(struct pt_regs * regs,
-                               long error_code)
+void do_simd_coprocessor_error(struct pt_regs * regs)
 {
     printk("SIMD copro error\n");
 }
 
-void do_spurious_interrupt_bug(struct pt_regs * regs,
-                               long error_code)
+void do_spurious_interrupt_bug(struct pt_regs * regs)
 {
 }
 
@@ -189,7 +207,6 @@ static trap_info_t trap_table[] = {
     {  5, 3, __KERNEL_CS, _P (unsigned long)bounds                      },
     {  6, 0, __KERNEL_CS, _P (unsigned long)invalid_op                  },
     {  7, 0, __KERNEL_CS, _P (unsigned long)device_not_available        },
-    {  8, 0, __KERNEL_CS, _P (unsigned long)double_fault                },
     {  9, 0, __KERNEL_CS, _P (unsigned long)coprocessor_segment_overrun },
     { 10, 0, __KERNEL_CS, _P (unsigned long)invalid_TSS                 },
     { 11, 0, __KERNEL_CS, _P (unsigned long)segment_not_present         },
index 4a4708ddd5adf67c203b87cf3ab89d2961ffee58..0f37d596f7b379d7b91a7736aec3e7b17f0e1e99 100644 (file)
@@ -6,7 +6,42 @@
 
 #define ENTRY(X) .globl X ; X :
 .globl _start, shared_info
-                        
+
+#define SAVE_ALL \
+        cld; \
+        pushq %rdi; \
+        pushq %rsi; \
+        pushq %rdx; \
+        pushq %rcx; \
+        pushq %rax; \
+        pushq %r8; \
+        pushq %r9; \
+        pushq %r10; \
+        pushq %r11; \
+        pushq %rbx; \
+        pushq %rbp; \
+        pushq %r12; \
+        pushq %r13; \
+        pushq %r14; \
+        pushq %r15;
+
+#define RESTORE_ALL \
+        popq  %r15; \
+        popq  %r14; \
+        popq  %r13; \
+        popq  %r12; \
+        popq  %rbp; \
+        popq  %rbx; \
+        popq  %r11; \
+        popq  %r10; \
+        popq  %r9; \
+        popq  %r8; \
+        popq  %rax; \
+        popq  %rcx; \
+        popq  %rdx; \
+        popq  %rsi; \
+        popq  %rdi
+
 _start:
         cld
         movq stack_start(%rip),%rsp
@@ -23,56 +58,165 @@ shared_info:
         .org 0x2000
 
 ENTRY(hypervisor_callback)
+        popq  %rcx
+        popq  %r11
+        iretq
 
 ENTRY(failsafe_callback)
-      iret
-                
+        popq  %rcx
+        popq  %r11
+        iretq
+
+error_code:
+        SAVE_ALL
+        movq  %rsp,%rdi
+        movl  15*8+4(%rsp),%eax
+        leaq  exception_table(%rip),%rdx
+        callq *(%rdx,%rax,8)
+        RESTORE_ALL
+        addq  $8,%rsp
+        iretq
+                        
 ENTRY(divide_error)
+        popq  %rcx
+        popq  %r11
        pushq $0
-
+        movl  $TRAP_divide_error,4(%rsp)
+        jmp   error_code
+        
 ENTRY(coprocessor_error)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_copro_error,4(%rsp)
+        jmp   error_code
 
 ENTRY(simd_coprocessor_error)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_simd_error,4(%rsp)
+        jmp   error_code
 
 ENTRY(device_not_available)
-        iret
+        popq  %rcx
+        popq  %r11
+        movl  $TRAP_no_device,4(%rsp)
+        jmp   error_code
 
 ENTRY(debug)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_debug,4(%rsp)
+        jmp   error_code
 
 ENTRY(int3)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_int3,4(%rsp)
+        jmp   error_code
 
 ENTRY(overflow)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_overflow,4(%rsp)
+        jmp   error_code
 
 ENTRY(bounds)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_bounds,4(%rsp)
+        jmp   error_code
 
 ENTRY(invalid_op)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_invalid_op,4(%rsp)
+        jmp   error_code
 
 ENTRY(coprocessor_segment_overrun)
+        popq  %rcx
+        popq  %r11
        pushq $0
-
-ENTRY(double_fault)
+        movl  $TRAP_copro_seg,4(%rsp)
+        jmp   error_code
 
 ENTRY(invalid_TSS)
+        popq  %rcx
+        popq  %r11
+        movl  $TRAP_invalid_tss,4(%rsp)
+        jmp   error_code
 
 ENTRY(segment_not_present)
+        popq  %rcx
+        popq  %r11
+        movl  $TRAP_no_segment,4(%rsp)
+        jmp   error_code
 
 ENTRY(stack_segment)
+        popq  %rcx
+        popq  %r11
+        movl  $TRAP_stack_error,4(%rsp)
+        jmp   error_code
 
 ENTRY(general_protection)
+        popq  %rcx
+        popq  %r11
+        movl  $TRAP_gp_fault,4(%rsp)
+        jmp   error_code
 
 ENTRY(alignment_check)
+        popq  %rcx
+        popq  %r11
+        movl  $TRAP_alignment_check,4(%rsp)
+        jmp   error_code
 
+ENTRY(virt_cr2)
+        .quad 0
 ENTRY(page_fault)
-
+        popq  %rcx
+        popq  %r11
+        popq  virt_cr2(%rip)
+        movl  $TRAP_page_fault,4(%rsp)
+        jmp   error_code
+        
 ENTRY(machine_check)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_machine_check,4(%rsp)
+        jmp   error_code
 
 ENTRY(spurious_interrupt_bug)
+        popq  %rcx
+        popq  %r11
        pushq $0
+        movl  $TRAP_spurious_int,4(%rsp)
+        jmp   error_code
+
+ENTRY(exception_table)
+        .quad do_divide_error
+        .quad do_debug
+        .quad 0 # nmi
+        .quad do_int3
+        .quad do_overflow
+        .quad do_bounds
+        .quad do_invalid_op
+        .quad 0
+        .quad 0
+        .quad do_coprocessor_segment_overrun
+        .quad do_invalid_TSS
+        .quad do_segment_not_present
+        .quad do_stack_segment
+        .quad do_general_protection
+        .quad do_page_fault
+        .quad do_spurious_interrupt_bug
+        .quad do_coprocessor_error
+        .quad do_alignment_check
+        .quad do_machine_check
+        .quad do_simd_coprocessor_error
index 2ff1455820307c36719d737c12226f59ceac6424..a4ccdf21bc8ca438c0c1adfd41bb5fe66f489030 100644 (file)
@@ -85,109 +85,79 @@ void startup_cpu_idle_loop(void)
 
 static long no_idt[2];
 static int reboot_mode;
-int reboot_thru_bios = 0;
-
-#ifdef CONFIG_SMP
-int reboot_smp = 0;
-static int reboot_cpu = -1;
-/* shamelessly grabbed from lib/vsprintf.c for readability */
-#define is_digit(c)    ((c) >= '0' && (c) <= '9')
-#endif
-
 
 static inline void kb_wait(void)
 {
     int i;
 
-    for (i=0; i<0x10000; i++)
-        if ((inb_p(0x64) & 0x02) == 0)
+    for ( i = 0; i < 0x10000; i++ )
+        if ( (inb_p(0x64) & 0x02) == 0 )
             break;
 }
 
-
 void machine_restart(char * __unused)
 {
-#ifdef CONFIG_SMP
-    int cpuid;
-#endif
+    int i;
        
     if ( opt_noreboot )
     {
         printk("Reboot disabled on cmdline: require manual reset\n");
-        for ( ; ; ) __asm__ __volatile__ ("hlt");
+        for ( ; ; )
+            safe_halt();
     }
 
-#ifdef CONFIG_SMP
-    cpuid = GET_APIC_ID(apic_read(APIC_ID));
-
-    /* KAF: Need interrupts enabled for safe IPI. */
     __sti();
 
-    if (reboot_smp) {
-
-        /* check to see if reboot_cpu is valid 
-           if its not, default to the BSP */
-        if ((reboot_cpu == -1) ||  
-            (reboot_cpu > (NR_CPUS -1))  || 
-            !(phys_cpu_present_map & (1<<cpuid))) 
-            reboot_cpu = boot_cpu_physical_apicid;
-
-        reboot_smp = 0;  /* use this as a flag to only go through this once*/
-        /* re-run this function on the other CPUs
-           it will fall though this section since we have 
-           cleared reboot_smp, and do the reboot if it is the
-           correct CPU, otherwise it halts. */
-        if (reboot_cpu != cpuid)
-            smp_call_function((void *)machine_restart , NULL, 1, 0);
+    /* Ensure we are the boot CPU. */
+    if ( GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid )
+    {
+        smp_call_function((void *)machine_restart, NULL, 1, 0);
+        for ( ; ; )
+            safe_halt();
     }
 
-    /* if reboot_cpu is still -1, then we want a tradional reboot, 
-       and if we are not running on the reboot_cpu,, halt */
-    if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
-        for (;;)
-            __asm__ __volatile__ ("hlt");
-    }
     /*
      * Stop all CPUs and turn off local APICs and the IO-APIC, so
      * other OSs see a clean IRQ state.
      */
     smp_send_stop();
     disable_IO_APIC();
-#endif
+
 #ifdef CONFIG_VMX
     stop_vmx();
 #endif
 
-    if(!reboot_thru_bios) {
-        /* rebooting needs to touch the page at absolute addr 0 */
-        *((unsigned short *)__va(0x472)) = reboot_mode;
-        for (;;) {
-            int i;
-            for (i=0; i<100; i++) {
-                kb_wait();
-                udelay(50);
-                outb(0xfe,0x64);         /* pulse reset low */
-                udelay(50);
-            }
-            /* That didn't work - force a triple fault.. */
-            __asm__ __volatile__("lidt %0": "=m" (no_idt));
-            __asm__ __volatile__("int3");
+    /* Rebooting needs to touch the page at absolute address 0. */
+    *((unsigned short *)__va(0x472)) = reboot_mode;
+
+    for ( ; ; )
+    {
+        /* Pulse the keyboard reset line. */
+        for ( i = 0; i < 100; i++ )
+        {
+            kb_wait();
+            udelay(50);
+            outb(0xfe,0x64); /* pulse reset low */
+            udelay(50);
         }
-    }
 
-    panic("Need to reinclude BIOS reboot code\n");
+        /* That didn't work - force a triple fault.. */
+        __asm__ __volatile__("lidt %0": "=m" (no_idt));
+        __asm__ __volatile__("int3");
+    }
 }
 
 
 void __attribute__((noreturn)) __machine_halt(void *unused)
 {
     for ( ; ; )
-        __asm__ __volatile__ ( "cli; hlt" );
+        safe_halt();
 }
 
 void machine_halt(void)
 {
-    smp_call_function(__machine_halt, NULL, 1, 1);
+    watchdog_on = 0;
+    smp_call_function(__machine_halt, NULL, 1, 0);
     __machine_halt(NULL);
 }
 
index 2c11f71668507d48356e8e7886380894e9e93b52..38abb1d3b73a4e485d5a7bfd14dc8e2c1c4e40b9 100644 (file)
@@ -24,7 +24,7 @@
 
 /* No ring-3 access in initial page tables. */
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
 
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
index 7fc6323a93ed641d2e16b9f804ad6f4bc8de69b7..788e7c12415e5e6a654768615f36a0f2c71757f2 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/domain_page.h>
 
 /* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */
+#define __PTE_MASK (~(_PAGE_GLOBAL|_PAGE_DIRTY|_PAGE_PCD|_PAGE_PWT))
 int map_pages(
     root_pgentry_t *pt,
     unsigned long v,
@@ -62,7 +63,7 @@ int map_pages(
             {
                 newpg = (void *)alloc_xenheap_page();
                 clear_page(newpg);
-                *pl2e = mk_l2_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
+                *pl2e = mk_l2_pgentry(__pa(newpg) | (flags & __PTE_MASK));
             }
             pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v);
             if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) )
index bd82b4ef7cfe4cb71c2a01f0b3d4ca33ce0b674f..7f39c1694cb699ea7bd65b2e5d72ed95be8fa9f5 100644 (file)
@@ -23,9 +23,9 @@
 
 /* Allow ring-3 access in long mode as guest cannot use ring 1. */
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
-#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
-#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
+#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
+#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
+#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
 
 #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
 #define round_pgdown(_p)  ((_p)&PAGE_MASK)
index 03301855ecf5f505a5017a9bbfa73a779873cace..feb7ec342b67015ebde148cd34da3cb488e3187b 100644 (file)
@@ -298,7 +298,7 @@ exception_with_ints_disabled:
         testb $3,XREGS_cs(%rsp)         # interrupts disabled outside Xen?
         jnz   1b                        # it really does happen!
                                         #  (e.g., DOM0 X server)
-        movq  XREGS_rip(%rsp),%rdi
+        movq  %rsp,%rdi
         call  search_pre_exception_table
         testq %rax,%rax                 # no fixup code for faulting EIP?
         jz    FATAL_exception_with_ints_disabled
index 5bced9a509e30ff21145c92979af2898f0257896..dacf6ae55d3c51e8723605bcb89e2477f49acc51 100644 (file)
@@ -37,6 +37,7 @@ void *safe_page_alloc(void)
 }
 
 /* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */
+#define __PTE_MASK (~(_PAGE_GLOBAL|_PAGE_DIRTY|_PAGE_PCD|_PAGE_PWT))
 int map_pages(
     root_pgentry_t *pt,
     unsigned long v,
@@ -57,7 +58,7 @@ int map_pages(
         {
             newpg = safe_page_alloc();
             clear_page(newpg);
-            *pl4e = mk_l4_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
+            *pl4e = mk_l4_pgentry(__pa(newpg) | (flags & __PTE_MASK));
         }
 
         pl3e = l4_pgentry_to_l3(*pl4e) + l3_table_offset(v);
@@ -65,7 +66,7 @@ int map_pages(
         {
             newpg = safe_page_alloc();
             clear_page(newpg);
-            *pl3e = mk_l3_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
+            *pl3e = mk_l3_pgentry(__pa(newpg) | (flags & __PTE_MASK));
         }
 
         pl2e = l3_pgentry_to_l2(*pl3e) + l2_table_offset(v);
@@ -88,7 +89,7 @@ int map_pages(
             {
                 newpg = safe_page_alloc();
                 clear_page(newpg);
-                *pl2e = mk_l2_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
+                *pl2e = mk_l2_pgentry(__pa(newpg) | (flags & __PTE_MASK));
             }
             pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v);
             if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) )
index 350fec4b3bc3296feee1c04dec3b408032b3439c..9c8a62663a7a9b401b82d1c6e6c5c22be5785eed 100644 (file)
@@ -55,10 +55,10 @@ typedef l4_pgentry_t root_pgentry_t;
 #define root_pgentry_to_phys(_x) (l4_pgentry_to_phys(_x))
 
 /* Turn a typed table entry into a page index. */
-#define l1_pgentry_to_pfn(_x)   (l1_pgentry_val(_x) >> PAGE_SHIFT) 
-#define l2_pgentry_to_pfn(_x)   (l2_pgentry_val(_x) >> PAGE_SHIFT)
-#define l3_pgentry_to_pfn(_x)   (l3_pgentry_val(_x) >> PAGE_SHIFT)
-#define l4_pgentry_to_pfn(_x)   (l4_pgentry_val(_x) >> PAGE_SHIFT)
+#define l1_pgentry_to_pfn(_x)   (l1_pgentry_to_phys(_x) >> PAGE_SHIFT) 
+#define l2_pgentry_to_pfn(_x)   (l2_pgentry_to_phys(_x) >> PAGE_SHIFT)
+#define l3_pgentry_to_pfn(_x)   (l3_pgentry_to_phys(_x) >> PAGE_SHIFT)
+#define l4_pgentry_to_pfn(_x)   (l4_pgentry_to_phys(_x) >> PAGE_SHIFT)
 #define root_pgentry_to_pfn(_x) (l4_pgentry_to_pfn(_x))
 
 /* Pagetable walking. */